load('js/luaclient.js')

var  loginUrl = "https://ebank.bankofbeijing.com.cn/bccbpb/accountLogon.jsp?language=zh_CN"; //借记卡;
var cardIndex = 1;
// var html = "" ;

var v4_beijing_debit_java_funcs ={
    openHomePage : function(){
        //访问首页
        var indexHtml = get("https://ebank.bankofbeijing.com.cn/bccbpb/accountLogon.jsp?language=zh_CN");
        storeDataToFile(context, indexHtml, "index.html");

        //页面不为空
        context.put("indexHtml", indexHtml)
    },
    checkProxyAvailable :function() {

        var indexHtml = context.get("indexHtml")
        if(StringUtils.isBlank(indexHtml)) {
            return false
        }
        var doc = Jsoup.parse(indexHtml)
        logger.info("任务【 {} 】name='form1'的元素个数{}", context.get(LUA_TASK_KEY), doc.select("[name='form1']").size())

        return doc.select("[name='form1']").size() > 0
    },
    checkTargetWebsiteAvailable: function(){ return true },
    checkControlAvailable:function (){ return true},
    login:function(){
        show();
        //输入用户名和密码
        var usernameInputResult = luaFuncs.input_username(getLoginParams(context)[0]);

        var isUsernameInputCorrectFunc = function(usernameInputResult) {
            return usernameInputResult
        }

        var getUsernameInputErrorMsgFunc = function(usernameInputResult) {
            return "密码因控件输入错误"
        }
        assertTrueOrThrowException(usernameInputResult, isUsernameInputCorrectFunc, getUsernameInputErrorMsgFunc)
        logger.info("任务【 {} 】用户名输入成功", context.get(LUA_TASK_KEY))

        var passwordInputResult = luaFuncs.input_password(context.get(LUA_TASK_TOKEN));

        var isPasswordInputCorrectFunc = function(passwordInputResult) {
            return passwordInputResult
        }

        var getPasswordInputErrorMsgFunc = function(passwordInputResult) {
            return "密码因控件输入错误"
        }
        assertTrueOrThrowException(passwordInputResult, isPasswordInputCorrectFunc, getPasswordInputErrorMsgFunc)
        logger.info("任务【 {} 】密码输入成功", context.get(LUA_TASK_KEY))
        hide();


        //获取图片验证码
        var captchaPath = get_image_by_id("verifyImg");

        logger.info("任务【 {} 】图片验证码路径【 {} 】", context.get(LUA_TASK_KEY), captchaPath)
        var isCaptchaPathCorrectFunc = function(captchaPath) {
            return captchaPath !== null && captchaPath !== undefined && captchaPath !== 'path fail'
        }

        var getCaptchaPathErrorMsgFunc = function(captchaPath) {
            return "图片验证码获取失败"
        }
        assertTrueOrThrowException(captchaPath, isCaptchaPathCorrectFunc, getCaptchaPathErrorMsgFunc)
        logger.info("任务【 {} 】图片验证码获取成功", context.get(LUA_TASK_KEY))

        //识别及判定
        context.put(TASK_IMG_PATH, captchaPath);
        context.put(TASK_IMG_REGEX,"[0-9a-zA-Z]{4}");
        var imgCode = waitImgCodeBySecondsByJs(context,60,true,3);

        var isImgCodeCorrectFunc = function(imgCode) {
            return StringUtils.isNotBlank(imgCode) && imgCode.length === 4
        }

        var getImgCodeErrorMsgFunc = function(imgCode) {
            return "图片验证码错误"
        }
        assertTrueOrThrowException(imgCode, isImgCodeCorrectFunc, getImgCodeErrorMsgFunc)
        logger.info("任务【 {} 】图片验证码格式正确", context.get(LUA_TASK_KEY))


        luaFuncs.input_verifyCode(imgCode.toLowerCase());
        var imgCodeInputResult = luaFuncs.checkIfInput("verifyImg",imgCode);

        var isImgCodeInputCorrectFunc = function(imgCodeInputResult) {
            return imgCodeInputResult
        }

        var getImgCodeInputErrorMsgFunc = function(imgCodeInputResult) {
            return "图片验证码未输入"
        }
        assertTrueOrThrowException(imgCodeInputResult, isImgCodeInputCorrectFunc, getImgCodeInputErrorMsgFunc)
        logger.info("任务【 {} 】图片验证码输入成功", context.get(LUA_TASK_KEY))


        click_by_id("button"); //点击登录



        var msg = luaFuncs.isLoginOk();

        var i = 0;
        while (i++<2) {
            storeDataToFile(context,msg, "isLoginOk_"+i+".html");
            logger.info("北京银行，登录验证返回信息："+msg);
            if (equals("ok",msg)) {
                return;
            } else {
                var amsg = get_alert_msg();
                if (equals("",amsg) || equals("no",amsg)) {
                    var html = luaFuncs.getHtmlGb2312();
                    storeDataToFile(context, html, "login_error_"+i+".html");
                    logger.info("北京银行，登录验证错误返回信息："+html);
                    var doc = Jsoup.parse(html);
                    if (doc.select("#Page_content1").size() > 0) {
                        logger.info("北京银行，包含确认页，再次判断");
                        msg = luaFuncs.isLoginOk();
                        continue;
                    } else if (doc.select("#Page_right").size() > 0) {
                        logger.info("北京银行，包含主页，成功");
                        return;
                    } else if (doc.select(".info_result_ditail").size() > 0) {
                        amsg = doc.select(".info_result_ditail").text();
                        logger.info("北京银行，包含错误页，获取错误信息:{}",amsg);
                    } else {
                        logger.info("北京银行，未知页面，再次判断");
                        msg = luaFuncs.isLoginOk();
                        continue;
                    }
                }

                var isImgCodeCorrectFunc = function(amsg) {
                    return !(amsg.contains("验证码错误") || amsg.contains("验证码不能为空"))
                }

                var getImgCodeErrorMsgFunc = function(amsg) {
                    return amsg
                }
                assertTrueOrThrowException(amsg, isImgCodeCorrectFunc, getImgCodeErrorMsgFunc)
            }
        }
    },
    crawl :function() {
        logger.info("北京银行开始抓取，taskKey:{}", context.get(LUA_TASK_KEY));
        //存储对象
        var data = new CreditCardAllData();
        data.setBankName("北京银行");
        data.setCardId(UUID.randomUUID().toString());
        data.setCardType("借记卡");
        crawlDebitInfo(data); //基本信息
        crawlDebitTransInfo(data); //账户明细
        crawlDebitDeposits(data); //存款信息

        var dataList = new ArrayList();
        dataList.add(data);
        context.put(DEBIT_DATA, dataList);
    },
    exitLogin :function () {}
}

function  getInterest(s){
    if(StringUtils.isNotBlank(s) && s.contains("%")){
        logger.info("beijing bank transfer :{}to bigdecimal interest. ",s);
        s=removeIllegal(s.substring(0,s.indexOf("%")));
        if (s==null) return null;
        var d = new BigDecimal(s);//.divide(new BigDecimal(100));
        return d ;
    }
    return null;
}

function crawlDebitInfo(data) {
    try{
        // TODO 北京银行借记卡基本信息抓取
        //		((BEIJINGDebitClient)getLuaClient()).hide();
        data.setCashBalance(null);
        data.setCashLimit(null);
        data.setCreditLimit(null);
        var html = luaFuncs.crawlAccountInfo(); //抓取基本信息 包含存款记录 不包含存款明细
        storeDataToFile(context,html, cardIndex+"_card_deposits_1.html");
        var doc = Jsoup.parse(html);
        var forms = doc.select("form[name='accForm']");
        if(null!== forms&&forms.size()>0){
            var form = forms.get(0);
            var tds = form.select("td");
            if(tds.size()>=4){
                var cradno = tds.get(1).text();
                if(StringUtils.isNotBlank(cradno)){
                    data.setFullCardNum(cradno);
                    data.setCardNum(cradno.substring(cradno.length()-4));
                }
                var openbank =tds.get(3).text();
                data.setOpenBank(openbank);
            }
        }
        var trs = doc.select("#accInfo > tr");
        var totalb = new BigDecimal(0);
        if(null!== trs){
            var deposits=new ArrayList();
            data.setDeposits(deposits);
            var p = Pattern.compile(".*\\((.*)\\).*");
            for(var i =0;i<trs.size();i++){
                var tr = trs.get(i);
                var tds = tr.select("td");
                if(tds.size()>=9){
                    var d = new CreditCardTimeDeposit();
                    deposits.add(d);
                    d.setCurrencyType(getCurrencyTypeStr(tds.get(1).text()));
                    d.setDepositDate(!equals(tds.get(3).text(),"---") ?yyyy_MM_dd_PARSER.parse(getDateStr(tds.get(3).text(),"yyyy/MM/dd","yyyy-MM-dd")) :null);
                    d.setPeriod(null);
                    d.setDueDate(!equals(tds.get(4).text(),"---") ? yyyy_MM_dd_PARSER.parse(getDateStr(tds.get(4).text(),"yyyy/MM/dd","yyyy-MM-dd")) :null);
                    if(StringUtils.isNotBlank(tds.get(5).text())){
                        d.setInterest(new BigDecimal(String.format("%.3f", Double.parseDouble(tds.get(5).text().replaceAll("%", ""))/100)));//.divide(new BigDecimal(100)));
                    }
                    d.setBalance(getBigDecimal(tds.get(6).text()));
                    totalb=totalb.add(d.getBalance());
                    d.setDepositType(tds.get(2).text());

                    var click = tds.get(8);
                    var as = click.select("a");
                    if(as.size()>0){
                        var a = as.get(0);
                        var href = a.attr("href");
                        if(StringUtils.isNoneBlank(href)){
                            var m = p.matcher(href);
                            if(m.find()&&m.groupCount()>=1){
                                var parm = m.group(1);
                                parm=parm.replaceAll("'", "");
                                logger.info("beijing bank acount detail parameter: {}",parm);

                                var detail = luaFuncs.acountDetial(parm);
                                var openTime = Jsoup.parse(detail);
                                var trim = openTime.select(".info_content").text().split("\n")[0].trim();
                                storeDataToFile(context,detail, cardIndex+"_deposits_"+(i+1)+".html");
                                /*if(StringUtils.isBlank(data.getNameOnCard())){
                                 //										String rgx = "户名：[\\s|\\S]*户名：([\u4e00-\u9fa5]*)"; //户名：([\u4e00-\u9fa5]*)
                                 String rgx = "//.*(\\d{16}).*户名：(.*)//"; //户名：([\u4e00-\u9fa5]*)
                                 Pattern  pt = Pattern.compile(rgx);
                                 Matcher mt = pt.matcher(trim);
                                 if(mt.find()){
                                 data.setNameOnCard(mt.group(1));
                                 }
                                 }*/
                                var name = trim.substring(trim.indexOf("户名：")+3, trim.indexOf("基本信息")).trim().replaceAll("\\u00A0", "").replaceAll("\\s*", "");;
                                logger.info("持卡人:{}",name);
                                data.setNameOnCard(name);
                                var openTimeStr = openTime.select(".form2 > tbody:nth-child(1) > tr:nth-child(5) > td:nth-child(2)").text().trim().replaceAll("/", "-");
                                data.setOpenTime(yyyy_MM_dd_PARSER.parse(openTimeStr));
                                logger.info("crawled beijing bank acount detail information : {}",cardIndex+"_deposits_"+(i+1));
                                var ddoc = Jsoup.parse(detail);
                                var dtrs = ddoc.select("table > tbody >tr");
                                var lin1=getLineDetail(dtrs, 1, 4);
                                d.setDepositType(lin1[3]);
                                var lin2=getLineDetail(dtrs, 2, 4);
                                var irate = lin2[3].replace("%", "");
                                if(StringUtils.isNotBlank(irate)){
                                    d.setInterest(new BigDecimal(String.format("%.3f", Double.parseDouble(irate)/100)));
                                }
                                var lin3=getLineDetail(dtrs, 3, 4);
                                d.setCurrencyType(getCurrencyTypeStr(lin3[1]));
                                var lin4=getLineDetail(dtrs, 4, 4);
                                d.setDepositDate(yyyy_MM_dd_PARSER.parse(lin4[1].replaceAll("\\/", "-")));
                                var lin5=getLineDetail(dtrs, 5, 4);
                                d.setBalance(getBigDecimal(lin5[1]));
                            }
                        }
                    }
                }
            }
        }
        data.setBalance(totalb);
        logger.info("北京银行 {}，解析基本信息、存款信息完成！",  context.get(LUA_TASK_KEY));
    } catch (e) {
        print(e)
        logger.info("北京银行 {} ，解析基本信息、存款信息异常: {}", context.get(LUA_TASK_KEY), e);
        statCaughtException(context, e);
    }
}

//获取金额类型 人民币、 美元
function getCurrencyTypeStr(str) {
    if (str == null || equals(str,"")) return "";
    if (str.contains("RMB") || str.contains("CNY") || str.contains("￥") || str.contains("人民币")) {
        return "CNY";
    } else {
        return "USD";
    }
}

function  getLineDetail(trs, idx, len){
    var res = new StringArray(len);

    var tr = trs.get(idx);
    var td = tr.select("td");
    if(td.size()<len){
        return res;
    }
    for(var i =0;i<len ;i++){
        var str = td.get(i).text();
        res[i]=str;
    }
    return res;
}

function getBigDecimal(s){
    s = removeIllegal(s);
    if(StringUtils.isBlank(s)){
        return new BigDecimal(0);
    }
    return new BigDecimal(s);

}

function getDateStr( datestr,  from_format,  to_format) {
    if (datestr == null) return null;
    var d = TimeUtil.getTime(datestr.trim(), from_format);
    if (d==null) return "";
    return TimeUtil.getTimeStr(d, to_format);
}


function  crawlDebitTransInfo( data) {
    try {
        // TODO 北京银行借记卡账户历史
        var sdf = new SimpleDateFormat("yyyy-MM-dd");
        var d = new Date();
        var bills=new ArrayList();
        data.setBills(bills);
        /*List<String> monthFirstDay = getMonthFirstDay();
         List<String> monthLastDay = getMonthLastDay();*/
        for(var i=0;i<12;i++){
            var b = new BillAllData();
            bills.add(b);
            b.setBankName("北京银行");
            b.setBillType("");
            var cld = Calendar.getInstance();
            cld.setTime(d);
            if(Integer.parseInt(cld.get(Calendar.DAY_OF_MONTH))<=1){
                cld.set(Integer.parseInt(Calendar.DAY_OF_MONTH), 0);
                d=cld.getTime();
            }
            var end=sdf.format(d);
            d=getOneMonthBefore(d);
            var start=sdf.format(d);
            b.setBillDate(yyyy_MM_dd_PARSER.parse(start));
            b.setBillMonth(getDateStr(start, "yyyy-MM-dd", "yyyy-MM"));
            b.setBillId(UUID.randomUUID().toString());
            var file = luaFuncs.crawlHisAccounts(start, end);
//				String file = ((BEIJINGDebitClient)getLuaClient()).crawlHisAccounts(monthFirstDay.get(11), monthLastDay.get(0));
            storeDataToFile( context,file, cardIndex+"_bills_"+start+".html");
//				getHtmlStorageHelper().store( file, cardIndex+"_bills_.html", "utf-8");
            logger.info("successfully crawled beijing tradedetail.");
            parseDetailInfo(data,b,file);
        }
    } catch (e) {
        logger.info("北京银行，抓crawlDebitTransInfo明细异常:{}",e);
        statCaughtException(context, e);
    }
}

function  parseDetailInfo(data, bill,  file) {
    try {

        var doc = Jsoup.parse(file);
        var cl1 = doc.select(".form_column1");
        var cl2 = doc.select(".form_column2");
        var  shopping_sheets=new ArrayList();
        bill.setShoppingSheets(shopping_sheets);
        var idx=1;
        for(var i =0;i<cl1.size();i++){
            var c = cl1.get(i);
            var e = getExpense(c);
            e.setOrderIndex(idx++);
            e.setCardNum(data.getCardNum());
            shopping_sheets.add(e);
        }
        for(var i =0;i<cl2.size();i++){
            var c = cl2.get(i);
            var e = getExpense(c);
            e.setOrderIndex(idx++);
            e.setCardNum(data.getCardNum());
            shopping_sheets.add(e);
        }

        bill.setNewBalance(null);
        bill.setUsdNewBalance(null);
        bill.setMinPayment(null);
        bill.setUsdMinPayment(null);
        bill.setLastBalance(null);
        bill.setUsdLastBalance(null);
        bill.setLastPayment(null);
        bill.setUsdLastPayment(null);
        bill.setNewCharges(null);
        bill.setUsdNewCharges(null);
        bill.setInterest(null);
        bill.setUsdInterest(null);
        bill.setCreditLimit(null);
        bill.setCreditLimit(null);
        bill.setUsdCreditLimit(null);
        bill.setCashLimit(null);
        bill.setCashLimit(null);
        bill.setUsdCashLimit(null);
    } catch(e) {
        logger.info("北京银行，解析parseDetailInfo明细异常:{}",e);
        statCaughtException(context, e);
    }
}


function  getExpense( c) {
    var e = new Expense();
    try {
        e.setId(UUID.randomUUID().toString());
        var tds = c.select("td");
        e.setTransDate(yyyy_MM_dd_HH_mm_ss_PARSER.parse(tds.get(1).text().replaceAll("\\/", "-") + " 00:00:00"));
        e.setPostDate(yyyy_MM_dd_PARSER.parse(tds.get(1).text().replaceAll("\\/", "-")));
        e.setDescription(tds.get(2).text());
        e.setCurrencyType("CNY");
        var tradetype=tds.get(3).text();//支出,收入
        var acount = removeIllegal(tds.get(4).text().trim());
        if (acount !== null) {
            if(tradetype.contains("收入")){
                e.setAmountMoney(new BigDecimal(acount).negate());
                e.setCategory(CategoryUtil.getDebitCategory(tds.get(2).text(),"-" + acount));
            }else{
                e.setAmountMoney(new BigDecimal(acount));
                e.setCategory(CategoryUtil.getDebitCategory(tds.get(2).text(), acount));
            }
        }
        var balance = removeIllegal(tds.get(5).text().trim());
        if (balance !== null)
            e.setBalance(new BigDecimal(balance));
        e.setTransAddr(tds.get(6).text());
    } catch (e) {
        logger.info("北京银行，解析账户Expense明细详情异常:{}",e);
        statCaughtException(context, e);
    }
    return e;
}


/**
 * 获取6个月的第一天  格式:2017-01-01
 * @return
 * @throws Exception
 */

function  getMonthFirstDay(){
    var lst = new ArrayList();

    var calendar = new GregorianCalendar();
    var dfdate = new SimpleDateFormat("yyyy-MM-dd");

    for (var i = 0; i < 12; i++) {

        calendar.setTime(new Date());
        calendar.add(Calendar.MONTH, -1 * i);

        var gcLast = Calendar.getInstance();
        gcLast.setTime(calendar.getTime());
        gcLast.set(Calendar.DAY_OF_MONTH, 1);
        lst.add(dfdate.format(gcLast.getTime()));
    }
    return lst;
}


/**
 * 获取六个月的最后一天,当月就返回到今天
 */
function  getMonthLastDay(){
    var lst = new ArrayList();

    var calendar = new GregorianCalendar();

    var dfdate = new SimpleDateFormat("yyyy-MM-dd");

    for (var i = -1; i < 11; i++) {

        calendar.setTime(new Date());
        calendar.add(Calendar.MONTH, -1 * i);

        var gcLast =  Calendar.getInstance();
        gcLast.setTime(calendar.getTime());
        gcLast.set(Calendar.DATE, 1);
        gcLast.add(Calendar.DATE, -1);
        if (gcLast.getTime().after(new Date())) {
            lst.add(dfdate.format(new Date()));
        } else {
            lst.add(dfdate.format(gcLast.getTime()));
        }
    }
    return lst;
}


function  getOneMonthBefore(d){
    var c = Calendar.getInstance();
    c.setTime(d);
    var dayofmonth=c.get(Calendar.DAY_OF_MONTH);
    dayofmonth = Integer.parseInt(dayofmonth);
    if(dayofmonth<=1){
        c.add(Calendar.MONTH, -1);
    }
    c.set(Calendar.DAY_OF_MONTH, 1);
    return c.getTime();
}

function   removeIllegal( str) {
    if (str == null) return str;
    str = str.replaceAll("[^\\d.]+", "");
    return "".equals(str)?null:str;
}

function  crawlDebitDeposits(data) {
    // TODO 北京银行借记卡存款信息抓取
//		((BEIJINGDebitClient)getLuaClient()).acountDetial("");
    logger.info("crawl debit detail finish..");
}


var luaFuncs = {
    /**
     * 输入密码，都是控件
     *
     * @param password
     * @return
     */
    input_password :function(password) {
        var map = new HashMap();
        map.put("method", "input_password");
        map.put("password", password);
        return sendAndReceive(map);
    },

    /**
     * 帐号
     * @return
     */
    input_username :function(cardNo) {
        var map = new HashMap();
        map.put("method", "input_username");
        map.put("cardNo", cardNo);
        return sendAndReceive(map);
    },
    /**
     * 输入验证码
     *
     * @param code
     * @return
     */
    input_verifyCode :function(code) {
        var map = new HashMap();
        map.put("method", "input_verifyCode");
        map.put("captcha", code);
        return sendAndReceive(map);
    },

    checkIfInput : function(id,value){
        var map = new LinkedHashMap();
        map.put("method", "checkIfInput");
        map.put("id", id);
        map.put("value", value);
        return Boolean.valueOf(sendAndReceive(map));
    },
    /**
     * 登录是否成功
     *
     * @return
     */
    isLoginOk :function() {
        var map = new HashMap();
        map.put("method", "isLoginOk");
        return sendAndReceive(map);
    },

    /**
     * 获取当前页面的html gb2312
     *
     * @return
     */
    getHtmlGb2312 :function() {
        var map = new HashMap();
        map.put("method", "GetHtmlGb2312");
        return sendAndReceive(map);
    },

    /**
     * 账户历史
     *
     * @param startDate
     *            --开始时间 yyyy-MM-dd
     * @param endDate
     *            --结束时间yyyy-MM-dd
     * @return
     */
    crawlHisAccounts :function (startDate, endDate) {
        var map = new HashMap();
        map.put("method", "crawlHisAccounts");
        map.put("startDate", startDate);
        map.put("endDate", endDate);
        return sendAndReceive(map);
    },

    /**
     * 北京银行借记卡信息
     *
     * @return
     */
    crawlAccountInfo :function() {
        var map = new HashMap();
        map.put("method", "crawlAccountInfo");
        return sendAndReceive(map);
    },

    /**
     * 北京银行借记卡信息
     *
     * @return
     */
    acountDetial :function(parm) {
        var map = new HashMap();
        map.put("method", "acountDetial");
        map.put("jsparm", parm);
        return sendAndReceive(map);
    }
}